package com.example.management.oa.service.impl

import com.example.management.common.service.DictService
import com.example.management.common.utils.DateUtils
import com.example.management.common.utils.PageUtils
import com.example.management.oa.dao.NotifyDao
import com.example.management.oa.dao.NotifyRecordDao
import com.example.management.oa.domain.NotifyDO
import com.example.management.oa.domain.NotifyRecordDO
import com.example.management.oa.service.NotifyService
import com.example.management.system.dao.UserDao
import com.example.management.system.service.SessionService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.messaging.simp.SimpMessagingTemplate
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*
import java.util.concurrent.LinkedBlockingDeque
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit


@Service
class NotifyServiceImpl : NotifyService {
    @Autowired
    private val notifyDao: NotifyDao? = null
    @Autowired
    private val recordDao: NotifyRecordDao? = null
    @Autowired
    private val userDao: UserDao? = null
    @Autowired
    private val dictService: DictService? = null
    @Autowired
    private val sessionService: SessionService? = null
    @Autowired
    private val template: SimpMessagingTemplate? = null

    override operator fun get(id: Long?): NotifyDO {
        val rDO = notifyDao!!.get(id)
        rDO.type = (dictService!!.getName("oa_notify_type", rDO.type!! ))
        return rDO
    }

    override fun list(map: Map<String, Any>): List<NotifyDO> {
        val notifys = notifyDao!!.list(map)
        for (notifyDO in notifys) {
            notifyDO.type = (dictService!!.getName("oa_notify_type", notifyDO.type!!))
        }
        return notifys
    }

    override fun count(map: Map<String, Any>): Int {
        return notifyDao!!.count(map)
    }

    @Transactional(rollbackFor = arrayOf(Exception::class))
    override fun save(notify: NotifyDO): Int {
        notify.updateDate = (Date())
        val r = notifyDao!!.save(notify)
        // 保存到接受者列表中
        val userIds = notify.userIds
        val notifyId = notify.id
        val records = ArrayList<NotifyRecordDO>()
        if (userIds != null) {
            for (userId in userIds) {
                val record = NotifyRecordDO()
                record.notifyId = (notifyId)
                record.userId = (userId)
                record.isRead = (0)
                records.add(record)
            }
        }
        recordDao!!.batchSave(records)
        //给在线用户发送通知
        val executor = ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, LinkedBlockingDeque())
        executor.execute {
            for (userDO in sessionService!!.listOnlineUser()) {
                if (userIds != null) {
                    for (userId in userIds) {
                        if (userId == userDO.userId) {
                            template!!.convertAndSendToUser(userDO.toString(), "/queue/notifications", "新消息：" + notify.title )
                        }
                    }
                }
            }
        }
        executor.shutdown()
        return r
    }

    override fun update(notify: NotifyDO): Int {
        return notifyDao!!.update(notify)
    }

    @Transactional
    override fun remove(id: Long?): Int {
        recordDao!!.removeByNotifbyId(id)
        return notifyDao!!.remove(id)
    }

    @Transactional
    override fun batchRemove(ids: Array<Long>): Int {
        recordDao!!.batchRemoveByNotifbyId(ids)
        return notifyDao!!.batchRemove(ids)
    }


    override fun selfList(map: Map<String, Any>): PageUtils {
        val rows = notifyDao!!.listDTO(map)
        for (notifyDTO in rows) {
            notifyDTO.before = (DateUtils.getTimeBefore(notifyDTO.updateDate!!))
            notifyDTO.sender = (userDao!!.get(notifyDTO.createBy).name )
        }
        return PageUtils(rows, notifyDao!!.countDTO(map))
    }

}